package com.ai.imagetext.util;

import com.ai.imagetext.exception.FileUploadException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.UUID;

@Slf4j
public class FileUtils {
    
    private static final List<String> ALLOWED_EXTENSIONS = List.of(".jpg", ".jpeg", ".png", ".gif", ".webp");
    private static final List<String> ALLOWED_MIME_TYPES = List.of(
        "image/jpeg", "image/jpg", "image/png", "image/gif", "image/webp"
    );
    
    /**
     * 验证文件类型
     */
    public static void validateFile(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            throw new FileUploadException("文件不能为空");
        }
        
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || originalFilename.trim().isEmpty()) {
            throw new FileUploadException("文件名不能为空");
        }
        
        // 验证文件扩展名
        String extension = getFileExtension(originalFilename).toLowerCase();
        if (!ALLOWED_EXTENSIONS.contains(extension)) {
            throw new FileUploadException("不支持的文件格式，请上传 JPG、PNG、GIF 或 WebP 格式的图片");
        }
        
        // 验证MIME类型
        String contentType = file.getContentType();
        if (contentType == null || !ALLOWED_MIME_TYPES.contains(contentType.toLowerCase())) {
            throw new FileUploadException("不支持的文件类型：" + contentType);
        }
        
        // 验证文件大小
        if (file.getSize() > 10485760L) { // 10MB
            throw new FileUploadException("文件大小不能超过10MB");
        }
    }
    
    /**
     * 生成唯一文件名
     */
    public static String generateUniqueFileName(String originalFilename) {
        String extension = getFileExtension(originalFilename);
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
        String uuid = UUID.randomUUID().toString().replace("-", "").substring(0, 8);
        return timestamp + "_" + uuid + extension;
    }
    
    /**
     * 获取文件扩展名
     */
    public static String getFileExtension(String filename) {
        if (filename == null || filename.isEmpty()) {
            return "";
        }
        int lastDotIndex = filename.lastIndexOf('.');
        return lastDotIndex > 0 ? filename.substring(lastDotIndex) : "";
    }
    
    /**
     * 创建目录
     */
    public static void createDirectoryIfNotExists(String directoryPath) {
        try {
            Path path = Paths.get(directoryPath);
            if (!Files.exists(path)) {
                Files.createDirectories(path);
                log.info("Created directory: {}", directoryPath);
            }
        } catch (IOException e) {
            throw new FileUploadException("无法创建目录：" + directoryPath, e);
        }
    }
    
    /**
     * 保存文件
     */
    public static void saveFile(MultipartFile file, String filePath) {
        try {
            Path path = Paths.get(filePath);
            Files.write(path, file.getBytes());
            log.info("File saved: {}", filePath);
        } catch (IOException e) {
            throw new FileUploadException("文件保存失败：" + filePath, e);
        }
    }
    
    /**
     * 删除文件
     */
    public static boolean deleteFile(String filePath) {
        try {
            Path path = Paths.get(filePath);
            boolean deleted = Files.deleteIfExists(path);
            if (deleted) {
                log.info("File deleted: {}", filePath);
            }
            return deleted;
        } catch (IOException e) {
            log.error("Failed to delete file: {}", filePath, e);
            return false;
        }
    }
    
    /**
     * 获取图片尺寸
     */
    public static Dimension getImageDimensions(MultipartFile file) {
        try {
            BufferedImage image = ImageIO.read(file.getInputStream());
            if (image != null) {
                return new Dimension(image.getWidth(), image.getHeight());
            }
        } catch (IOException e) {
            log.warn("Failed to read image dimensions", e);
        }
        return new Dimension(0, 0);
    }
    
    /**
     * 生成缩略图
     */
    public static byte[] generateThumbnail(MultipartFile file, int size) {
        try {
            BufferedImage originalImage = ImageIO.read(file.getInputStream());
            if (originalImage == null) {
                throw new FileUploadException("无法读取图片文件");
            }
            
            // 计算缩略图尺寸
            int originalWidth = originalImage.getWidth();
            int originalHeight = originalImage.getHeight();
            
            int thumbnailWidth, thumbnailHeight;
            if (originalWidth > originalHeight) {
                thumbnailWidth = size;
                thumbnailHeight = (int) ((double) originalHeight / originalWidth * size);
            } else {
                thumbnailHeight = size;
                thumbnailWidth = (int) ((double) originalWidth / originalHeight * size);
            }
            
            // 创建缩略图
            BufferedImage thumbnailImage = new BufferedImage(thumbnailWidth, thumbnailHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = thumbnailImage.createGraphics();
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.drawImage(originalImage, 0, 0, thumbnailWidth, thumbnailHeight, null);
            g2d.dispose();
            
            // 转换为字节数组
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            String format = getImageFormat(file.getContentType());
            ImageIO.write(thumbnailImage, format, baos);
            
            return baos.toByteArray();
            
        } catch (IOException e) {
            throw new FileUploadException("生成缩略图失败", e);
        }
    }
    
    /**
     * 根据MIME类型获取图片格式
     */
    private static String getImageFormat(String mimeType) {
        if (mimeType == null) return "jpg";
        
        switch (mimeType.toLowerCase()) {
            case "image/png":
                return "png";
            case "image/gif":
                return "gif";
            case "image/webp":
                return "webp";
            default:
                return "jpg";
        }
    }
    
    /**
     * 格式化文件大小
     */
    public static String formatFileSize(long size) {
        if (size < 1024) {
            return size + " B";
        } else if (size < 1024 * 1024) {
            return String.format("%.1f KB", size / 1024.0);
        } else if (size < 1024 * 1024 * 1024) {
            return String.format("%.1f MB", size / (1024.0 * 1024.0));
        } else {
            return String.format("%.1f GB", size / (1024.0 * 1024.0 * 1024.0));
        }
    }
}